package com.gdzn.signal.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.gdzn.common.core.utils.DateUtils;
import com.gdzn.common.core.utils.JsonUtil;
import com.gdzn.signal.mapper.DevCabinetMapper;
import com.gdzn.signal.mongo.document.DevCabinetMongo;
import com.gdzn.signal.mongo.document.DevDoorsMongo;
import com.gdzn.signal.enums.SignalEnum;
import com.gdzn.signal.mongo.service.*;
import com.gdzn.signal.vo.DevCabinetRspVo;
import com.gdzn.signal.service.IDevCabinetService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DevCabinetServiceImpl implements IDevCabinetService {

    @Autowired
    private IDevCabinetMongoService devCabinetMongoService;

    @Autowired
    private IDevDoorsMongoService devDoorsMongoService;

    @Autowired
    private DevCabinetMapper devCabinetMapper;


    /**
     * 处理电柜信号信息
     * @param jsonStr
     * @return
     */
    @Override
    public boolean saveOrUpdateCabinetInfo(String jsonStr) {
        //log.info("***saveOrUpdateCabinetInfo***start****");
        Map<String,Object> resultMap = JsonUtil.toMap(jsonStr);
        List<Map<String,Object>> attrMapList = (List<Map<String, Object>>) resultMap.get("attrList");
        //电柜信息
        DevCabinetMongo cabinet = new DevCabinetMongo();
        String devId = String.valueOf(resultMap.get("devId"));
        String isFull = String.valueOf(resultMap.get("isFull"));
        DevCabinetMongo cabinetOld = devCabinetMongoService.findById(devId);
        if(null!=cabinetOld && StringUtils.isNotEmpty(cabinetOld.getId())){
            BeanUtils.copyProperties(cabinetOld,cabinet);
        }
        cabinet.setId(devId);
        cabinet.setOnline("1");
        cabinet.setCabinetId(devId);
        attrMapList.forEach(attr ->{
            if(SignalEnum.SIGNAL15.getCode().equals(attr.get("id"))){
                cabinet.setStatus(String.valueOf(attr.get("value")));
            }
            if(SignalEnum.SIGNAL5.getCode().equals(attr.get("id"))){
                cabinet.setEnableStatus(String.valueOf(attr.get("value")));
            }
            if(SignalEnum.SIGNAL1.getCode().equals(attr.get("id"))){
                cabinet.setLongitude(String.valueOf(attr.get("value")));
            }
            if(SignalEnum.SIGNAL2.getCode().equals(attr.get("id"))){
                cabinet.setLatitude(String.valueOf(attr.get("value")));
            }
            if(SignalEnum.SIGNAL6.getCode().equals(attr.get("id"))){
                cabinet.setTemperature(String.valueOf(attr.get("value")));
            }
            if(SignalEnum.SIGNAL3.getCode().equals(attr.get("id"))){
                cabinet.setVoltage(String.valueOf(attr.get("value")));
            }
            if(SignalEnum.SIGNAL4.getCode().equals(attr.get("id"))){
                cabinet.setElectricCurrent(String.valueOf(attr.get("value")));
            }
        });

        //按仓门分组
        Map<String,List<Map<String,Object>>> doorMapList = attrMapList.stream().collect(Collectors.groupingBy(map -> {
            if(null!=map.get("doorId")){
                return map.get("doorId").toString();
            }else{
                return "null_value";
            }
        }));
        //仓门信息
        List<DevDoorsMongo> doorList = new ArrayList<>();
        doorMapList.forEach((doorId,tempList) ->{
            if("null_value".equals(doorId)){
                return;
            }
            String id = devId+"2024"+doorId;
            //仓门信息
            DevDoorsMongo doorsInfo = new DevDoorsMongo();
            DevDoorsMongo doorsInfOld = devDoorsMongoService.findById(id);
            if(null!=doorsInfOld && StringUtils.isNotEmpty(doorsInfOld.getId())){
                BeanUtils.copyProperties(doorsInfOld,doorsInfo);
            }
            doorsInfo.setId(id);
            doorsInfo.setDevId(devId);
            doorsInfo.setDoorId(doorId);
            doorsInfo.setUpdateTime(DateUtils.getNowDate());
            tempList.forEach(attr -> {
                if(SignalEnum.SIGNAL10.getCode().equals(attr.get("id"))){
                    doorsInfo.setBatteryId(String.valueOf(attr.get("value")));
                }
                if(SignalEnum.SIGNAL11.getCode().equals(attr.get("id"))){
                    doorsInfo.setElectricityLevel(String.valueOf(attr.get("value")));
                }
                if(SignalEnum.SIGNAL7.getCode().equals(attr.get("id"))){
                    doorsInfo.setDoorStatus(String.valueOf(attr.get("value")));
                }
                if(SignalEnum.SIGNAL9.getCode().equals(attr.get("id"))){
                    doorsInfo.setChargeStatus(String.valueOf(attr.get("value")));
                }

                if(SignalEnum.SIGNAL8.getCode().equals(attr.get("id"))){
                    doorsInfo.setEnableStatus(String.valueOf(attr.get("value")));
                }
                if(SignalEnum.SIGNAL14.getCode().equals(attr.get("id"))){
                    doorsInfo.setChargeTime(String.valueOf(attr.get("value")));
                }
                if(SignalEnum.SIGNAL16.getCode().equals(attr.get("id"))){
                    doorsInfo.setBatteryMalfunction(String.valueOf(attr.get("value")));
                }
                if(SignalEnum.SIGNAL17.getCode().equals(attr.get("id"))){
                    doorsInfo.setBatteryAlarm(String.valueOf(attr.get("value")));
                }
                if(SignalEnum.SIGNAL13.getCode().equals(attr.get("id"))){
                    doorsInfo.setBatteryTemperature(String.valueOf(attr.get("value")));
                }
                if(SignalEnum.SIGNAL13.getCode().equals(attr.get("id"))){
                    doorsInfo.setBatteryTemperature(String.valueOf(attr.get("value")));
                }
            });
            doorList.add(doorsInfo);
        });
        if("1".equals(isFull)){
            cabinet.setCabinCount(doorList.size());
        }
        cabinet.setUpdateTime(DateUtils.getNowDate());
        //保存电柜信息到MongoDB
        devCabinetMongoService.insert(cabinet);
        //log.info("***saveOrUpdateCabinetInfo***doorList:{}",doorList);
        devDoorsMongoService.insertAll(doorList);
        return true;
    }

    /**
     * 获取电柜信息
     * @param devId
     * @return
     */
    @Override
    public DevCabinetRspVo getDevCabinet(String devId) {
        DevCabinetRspVo cabinetRspVo = new DevCabinetRspVo();
        DevCabinetMongo cabinetOld = devCabinetMongoService.findById(devId);
        if(null==cabinetOld || StringUtils.isEmpty(cabinetOld.getId())){
            return null;
        }
        BeanUtils.copyProperties(cabinetOld,cabinetRspVo);
        DevDoorsMongo doorsMongoQuery = new DevDoorsMongo();
        doorsMongoQuery.setDevId(devId);
        List<DevDoorsMongo> doorList = devDoorsMongoService.findAll(doorsMongoQuery);
        doorList = doorList.stream().sorted((x,y)->
                Integer.compare(Integer.parseInt(x.getDoorId()),Integer.parseInt(y.getDoorId()))
        ).collect(Collectors.toList());
        cabinetRspVo.setDoorList(doorList);
        return cabinetRspVo;
    }

    /**
     * 多个条件查询设备和电池信息
     * @param paramMap
     * @return
     */
    @Override
    public DevCabinetRspVo getDevCabinetByMap(Map<String, String> paramMap) {
        String devId = paramMap.get("devId");
        String batterId = paramMap.get("batterId");

        DevCabinetRspVo cabinetRspVo = new DevCabinetRspVo();
        if(StringUtils.isNotEmpty(devId)&&StringUtils.isNotEmpty(batterId)){
            DevCabinetMongo cabinetOld = devCabinetMongoService.findById(devId);
            if(null==cabinetOld || StringUtils.isEmpty(cabinetOld.getId())){
                return null;
            }
            BeanUtils.copyProperties(cabinetOld,cabinetRspVo);
            DevDoorsMongo doorsMongoQuery = new DevDoorsMongo();
            doorsMongoQuery.setDevId(devId);
            doorsMongoQuery.setBatteryId(batterId);
            List<DevDoorsMongo> doorList = devDoorsMongoService.findAll(doorsMongoQuery);
            cabinetRspVo.setDoorList(doorList);
        }else if(StringUtils.isEmpty(devId)&&StringUtils.isNotEmpty(batterId)){
            DevDoorsMongo doorsMongoQuery = new DevDoorsMongo();
            doorsMongoQuery.setBatteryId(batterId);
            List<DevDoorsMongo> doorList = devDoorsMongoService.findAll(doorsMongoQuery);
            if(CollectionUtil.isEmpty(doorList)){
                return null;
            }
            DevCabinetMongo cabinetOld = devCabinetMongoService.findById(doorList.get(0).getDevId());
            if(null==cabinetOld && StringUtils.isEmpty(cabinetOld.getId())){
                return null;
            }
            BeanUtils.copyProperties(cabinetOld,cabinetRspVo);
            cabinetRspVo.setDoorList(doorList);
        }
        return cabinetRspVo;
    }

    /**
     * 更新仓门状态
     * doorStatus仓门状态：0 关，1 开
     * @param paramMap
     * @return
     */
    @Override
    public boolean updateDoorStatus(Map<String, String> paramMap) {
        log.info("***updateDoorStatus:{}",paramMap);
        String devId = paramMap.get("devId");
        String doorId = paramMap.get("doorId");
        String doorStatus = paramMap.get("doorStatus");
        DevDoorsMongo doorsMongoQuery = new DevDoorsMongo();
        doorsMongoQuery.setDevId(devId);
        doorsMongoQuery.setDoorId(doorId);
        List<DevDoorsMongo> doorList = devDoorsMongoService.findAll(doorsMongoQuery);
        log.info("***doorList:{};doorList:{}",doorList,doorList.size());
        if(CollectionUtil.isEmpty(doorList)){
            return false;
        }
        DevDoorsMongo cabinetOld = doorList.get(0);
        cabinetOld.setDoorStatus(doorStatus);
        devDoorsMongoService.insert(cabinetOld);
        log.info("***updateDoorStatus:{}",cabinetOld);
        return true;
    }

    @Override
    public boolean updateCabinetOnline(String devId, String online) {
        log.info("***updateCabinetOnline***devId:{},online:{}",devId,online);
        DevCabinetMongo cabinetMongo = devCabinetMongoService.findById(devId);
        if(null!=cabinetMongo){
            cabinetMongo.setOnline(online);
            devCabinetMongoService.update(cabinetMongo);
        }
        devCabinetMapper.updateCabinetOnline(devId, online);
        log.info("***updateCabinetOnline***end***");
        return true;
    }
}
